package com.yxj.ui;
import java.awt.*;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import javax.swing.*;

import javax.swing.table.DefaultTableModel;


import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import com.yxj.gm.SM2;
import com.yxj.util.SqlLiteUtil;
import com.yxj.util.UDiskUtil;
import org.apache.commons.lang.StringUtils;
import org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI;




@SuppressWarnings("serial")
public class SwingArea extends JFrame {
    static boolean uState = false;

    static String dbPth = "";

    public static void main(String[] args) {
        SwingArea.getInstance().initUI();
    }

    private static SwingArea instance = null;
    private SwingArea() {
    }
    public static SwingArea getInstance() {
        if (null == instance) {
            synchronized (SwingArea.class) {
                if (null == instance) {
                    instance = new SwingArea();
                }
            }
        }
        return instance;
    }


    public void initUI() {
        //
        Font f = new Font("微软雅黑", Font.PLAIN, 14);
        this.setTitle("密码加密管理工具");
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.dispose();
        this.setBounds(100, 100, 700, 340);

        JPanel panel = new JPanel();
        panel.setLayout(null);

        // 表头（列名）
        String[] columnNames = {"序号","应用名称", "密码",  "最后更新日期"};
        // 表格所有行数据
        //TODO从数据库中初始化
        Object[][] rowData;
        //System.out.println("数据库测试");
        SqlLiteUtil.sqlInit(dbPth);
        rowData=SqlLiteUtil.selectList();
        //System.out.println("数据库测试结束");

        SqlLiteUtil.sqlInit(dbPth);
        final int[] pwdCount = {SqlLiteUtil.selectPwdCount()};

        // 创建一个表格，指定 表头 和 所有行数据
//        JTable table = new JTable(rowData, columnNames);
        final DefaultTableModel tableModel = new DefaultTableModel(rowData, columnNames);

        final JTable table = new JTable(tableModel);
//        // 获取 表格模型
//        final TableModel tableModel = table.getModel();

        tableModel.addTableModelListener(e -> {
            int firstRow = e.getFirstRow();

            // 获取被改变的列
            int column = e.getColumn();

            if(column!=2){
                return;
            }

            Object valueAt = table.getValueAt(firstRow, 2);
            if(StringUtils.isBlank(valueAt.toString())){
                JOptionPane.showMessageDialog(null, "更新不能为空,修改未生效！╮(╯▽╰)╭", "警告！",JOptionPane.WARNING_MESSAGE);
                return;
            }
            Object id = table.getValueAt(firstRow, 0);
            table.setValueAt(new SimpleDateFormat("yyy-MM-dd hh:mm:ss").format(new Date()),firstRow,3);
            SqlLiteUtil.sqlInit(dbPth);
            SqlLiteUtil.updateById(new Integer(id.toString()), (String) valueAt);

            //System.out.println("修改后的id："+id);
            //System.out.println("修改后的值："+valueAt);
        });

        // 设置表格内容颜色
        table.setForeground(Color.BLACK);                   // 字体颜色
        table.setFont(new Font(null, Font.PLAIN, 14));      // 字体样式
        table.setSelectionForeground(Color.DARK_GRAY);      // 选中后字体颜色
        table.setSelectionBackground(Color.LIGHT_GRAY);     // 选中后字体背景
        table.setGridColor(Color.GRAY);                     // 网格颜色
        // 设置行高
        table.setRowHeight(30);

        // 第一列列宽设置为40
        table.getColumnModel().getColumn(0).setPreferredWidth(10);

        // 设置滚动面板视口大小（超过该大小的行数据，需要拖动滚动条才能看到）
        table.setPreferredScrollableViewportSize(new Dimension(400, 200));

        // 把 表格 放到 滚动面板 中（表头将自动添加到滚动面板顶部）
        JScrollPane scrollPane = new JScrollPane(table);

        scrollPane.setBounds(5,10,560,200);


        //U盘标题
        JLabel keysTitle = new JLabel("U盘状态：");
        keysTitle.setBounds(580, 10, 100, 30);
        keysTitle.setFont(f);

        JLabel uInfoTitle = new JLabel("未检测到U盘");
        uInfoTitle.setForeground(Color.RED);
        uInfoTitle.setBounds(580, 40, 120, 60);
        uInfoTitle.setFont(f);


        //U盘插入监听
        new Thread(()->{
            int sleepTime = 1000;
            boolean init = true;
            table.setVisible(false);
            while (true){
                    if(UDiskUtil.getRowData().size()==1){
                        try {
                            if(init){
                                uInfoTitle.setForeground(Color.ORANGE);
                                uInfoTitle.setText("<html>检测到U盘<br>解密中......<html>");
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                uState=true;
                                File keyFile = new File(File.listRoots()[File.listRoots().length-1]+"\\keyCyptoTool\\key.key");
                                if(!keyFile.exists()){
                                    uInfoTitle.setForeground(Color.RED);
                                    uInfoTitle.setText("<html>解密失败<br>未找到密钥文件......<html>");
                                    try {
                                        Thread.sleep(5000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    continue;
                                }

                                FileInputStream fileInputStream = new FileInputStream(keyFile);
                                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
                                String prikey = bufferedReader.readLine();
                                if(!SM2.checkPriKey(HexBin.decode(prikey),HexBin.decode(SqlLiteUtil.getPubKeyHex()))){
                                    uInfoTitle.setForeground(Color.RED);
                                    uInfoTitle.setText("<html>解密失败<br>密钥错误......<html>");
                                    try {
                                        Thread.sleep(5000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    continue;
                                }
                                dbPth=File.listRoots()[File.listRoots().length-1]+"\\keyCyptoTool\\keyCyptoTool.db";
                                SqlLiteUtil.setPriKeyHex(prikey);
                                // 更新Jtable数据
                                //System.out.println("数据库测试");
                                SqlLiteUtil.sqlInit(dbPth);
                                Object[][] data = SqlLiteUtil.selectList();
                                //System.out.println("数据库测试结束");
                                tableModel.setDataVector(data,columnNames);
                                init=false;
                            }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        uInfoTitle.setForeground(Color.green);
                        uInfoTitle.setText("已解密");

                        table.setVisible(true);

                    }else if (UDiskUtil.getRowData().size()==0){
                        uState=false;
                        init=true;
                        uInfoTitle.setForeground(Color.RED);
                        uInfoTitle.setText("未检测到U盘");
                        uState=false;
                        SqlLiteUtil.setPriKeyHex("");
                        table.setVisible(false);

                    }

                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();


        //名称标题
        JLabel nameLabel = new JLabel("应用名称：");
        nameLabel.setBounds(80, 220, 80, 30);
        nameLabel.setFont(f);

        //显示名称的文本框
        final JTextField nameTextField = new JTextField();
        nameTextField.setBounds(150,220,110,30);
        nameTextField.setFont(f);

        //密码标题
        JLabel pwdTitle = new JLabel("密码：");
        pwdTitle.setBounds(290, 220, 100, 30);
        pwdTitle.setFont(f);

        //显示密码的文本框
        final JTextField pwdTextField = new JTextField();
        pwdTextField.setBounds(330,220,150,30);
        pwdTextField.setFont(f);



        JButton addBtn = new JButton("添加");
        addBtn.setBounds(160,270,100,30);

        addBtn.addActionListener(e -> {
            if(!uState){
                JOptionPane.showMessageDialog(null, "请插入U盘！╮(╯▽╰)╭", "警告！",JOptionPane.WARNING_MESSAGE);
                return;
            }
            if(StringUtils.isBlank(nameTextField.getText())||StringUtils.isBlank(pwdTextField.getText())){
                JOptionPane.showMessageDialog(null, "添加内容不能为空,添加失败！╮(╯▽╰)╭", "警告！",JOptionPane.WARNING_MESSAGE);
                return;
            }
            pwdCount[0]++;
            String []rowValues = {pwdCount[0] +"",nameTextField.getText(),pwdTextField.getText(),new SimpleDateFormat("yyy-MM-dd hh:mm:ss").format(new Date())};
            tableModel.addRow(rowValues);
            SqlLiteUtil.sqlInit(dbPth);
            SqlLiteUtil.insert(pwdCount[0],nameTextField.getText(),pwdTextField.getText());
            nameTextField.setText("");
            pwdTextField.setText("");
        });



        addBtn.setUI(new BEButtonUI().setNormalColor(BEButtonUI.NormalColor.green));
        addBtn.setFont(new Font("宋体", Font.BOLD,15));
        addBtn.setForeground(Color.white);//字体颜色


        JButton deleteBtn = new JButton("删除");
        deleteBtn.setBounds(370,270,100,30);

        deleteBtn.addActionListener(e -> {
            if(!uState){
                JOptionPane.showMessageDialog(null, "请插入U盘！╮(╯▽╰)╭", "警告！",JOptionPane.WARNING_MESSAGE);
                return;
            }
            int selectedRow = table.getSelectedRow();//获得选中行的索引
            //System.out.println("选中的是："+selectedRow);

            if(selectedRow!=-1)  //存在选中行
            {
                // 操作数据库删除数据
                Object valueAt = table.getValueAt(selectedRow, 0);
                //System.out.println("操作数据库删除数据:"+valueAt);
                SqlLiteUtil.sqlInit(dbPth);
                SqlLiteUtil.deleteById(new Integer(valueAt.toString()));
                tableModel.removeRow(selectedRow);  //删除行
                pwdCount[0] --;

            }
        });
        deleteBtn.setUI(new BEButtonUI().setNormalColor(BEButtonUI.NormalColor.green));
        deleteBtn.setFont(new Font("宋体", Font.BOLD,15));
        deleteBtn.setForeground(Color.white);

        panel.add(scrollPane);

        panel.add(addBtn);
        panel.add(deleteBtn);

//        panel.add(stringTitle);
//        panel.add(stringField);

        panel.add(keysTitle);
        panel.add(uInfoTitle);

        panel.add(nameTextField);
        panel.add(nameLabel);

        panel.add(pwdTextField);
        panel.add(pwdTitle);

        this.setContentPane(panel);
//        this.pack();
        this.setLocationRelativeTo(null);

        this.setVisible(true);


    }


    public static String getDbPth() {
        return dbPth;
    }

    public static void setDbPth(String dbPth) {
        SwingArea.dbPth = dbPth;
    }
}
